package com.hxh.myAop;

import cn.hutool.core.collection.CollectionUtil;
import com.hxh.entity.Project;
import com.hxh.entity.output.ApiResult;
import com.hxh.service.ProjectConfigRecordService;
import com.hxh.service.ProjectDatasourceService;
import com.hxh.service.ProjectService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author HXH
 * @description: 记录项目版本变更，记录需要操作的类型，如重启、重新生成表代码、重新初始化项目
 */
@Aspect
@Component
@Slf4j
public class ProjectConfigRecordDatabaseTableAspect {

    @Autowired
    private ProjectConfigRecordService projectConfigRecordService;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private ProjectDatasourceService projectDatasourceService;


    /*************************数据源中数据表变更 标志处理 start********************************/
//    数据表信息发生变更，需要重新生成前后端代码
//    拦截方法：com.hxh.controller.TableConfigController的 update、add、editTableInfo
    @Around("execution(* com.hxh.controller.TableConfigController.update(..)) || " +
            "execution(* com.hxh.controller.TableConfigController.add(..)) || " +
            "execution(* com.hxh.controller.TableConfigController.editTableInfo(..))")
    public Object interceptTableChange(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        String tableName = null;

        boolean needProcess = true;
        // 根据不同方法提取 tableName 参数
        if (joinPoint.getSignature().getName().equals("update")) {
            tableName = (String) args[2]; // update(datasourceId, sql, tableName)
        } else if (joinPoint.getSignature().getName().equals("add")) {
            tableName = (String) args[2]; // add(datasourceId, addSql, tableName)
        } else if (joinPoint.getSignature().getName().equals("editTableInfo")) {
            tableName = (String) args[1]; // editTableInfo(datasourceId, tableName, tableDesc, oldTableName)
            String oldTableName = (String) args[3];
            if (oldTableName.equals(tableName)) {
                //只修改表注释，不做处理
                needProcess = false;
            }
        }

        Integer datasourceId = (Integer) args[0];

        // 执行原方法
        Object result = joinPoint.proceed();
        if (!needProcess) {
            return result;
        }

        // 判断是否执行成功
        ApiResult success = result instanceof ApiResult ? (ApiResult) result : ApiResult.fail("");
        if (success.isStatus()) {
            List<Project> projectList = projectService.selectByDatasourceId(datasourceId);
            if (CollectionUtil.isNotEmpty(projectList)){
                List<Integer> projectIdList = projectList.stream().map(Project::getId).collect(Collectors.toList());
                String mysqlDatabaseName = projectDatasourceService.selectById(datasourceId).getMysqlDatabaseName();
                processTableChange(projectIdList, mysqlDatabaseName + "." + tableName);
            }
        }
        return result;
    }

    private void processTableChange(List<Integer> projectIdList, String tableName) {
        // 触发前端/后端代码重建
        projectIdList.forEach(projectId -> {
            projectConfigRecordService.frontRebuildTables(projectId, tableName);
            projectConfigRecordService.backRebuildTables(projectId, tableName);
            projectConfigRecordService.addLocalVersion(projectId);
        });
    }

    /*************************数据源中数据表变更 标志处理 end********************************/

}
